\ifx\CCSTY\relax\endinput\else\let\CCSTY=\relax\fi % \input only once
% cc.sty: Latex style to typeset CC++ prorams with comments.
%
% Usage:
% \begin{cc}
%    ... CC++ program ...
% \end{cc}
%
% The program text is set verbatim in typewriter (\tt) font. Comments
% have the form  /! ... !/ or /* ... */ or // ... (end-of-line).
% /! comments are set in slanted font (\sl), the other comments in italic
% (\it). Comments are treated as normal TeX input, therefore they can contain
% macros and math; however, spaces are not ignored (e.g., if you write
% `\bf abc' there will be a space before abc; write `\bf{}abc' instead).
% Line breaks are maintained.
%
% The program lines are indented by \ccindent, by default 0. E.g.,
% you can set \ccindent=\parindent
%
% The comment signs (/! etc) are set in \commentfont, by default \tt. E.g.,
% you can set \let\commentfont=\rm if you want them in roman, or
% \let\commentfont=\relax if you want them in the same font as the rest
% of the comment.
%
% If you want to change the vertical spacing around the environment,
% do, e.g.,  \renewenvironment{cc}{\smallskip\setupcc}{\smallskip}
% (the default has \bigskip instead of \smallskip).
%
% Restrictions on the text between \begin{cc} ... \end{cc}:
% - No backslash (\) should occur as first character of the line in the
%   code (in a comment is fine).
% - \end{cc} should occur at the beginning of a line.
% - tab characters are not recognized.
% - The cc environment doesn't know about C strings. Therefore, /* etc.
%   are always interpreted as start of a comment, even if they are quoted.
%
%
%   Caltech, Pasadena, 1992  ---  Marcel van der Goot
%				  marcel@cs.caltech.edu
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% This is a pretty messy piece of code.
%

\edef\tmp{\the\catcode`\_} % to remember catcode
\catcode`\_=11 % to make private macros

\newdimen\ccindent
\newbox\cc_box % for building a line
\ccindent=0pt

% Starting a comment:
% `/' is made equal to \start_comment, which checks whether a `!', a `*', or
% a `/' follows. If so a comment is started.

\let\normal_slash=/

\def\start_comment{\futurelet\next\is_comment}

{
\catcode`\/=13 % active slash

\gdef\is_comment
   {\if!\next\let\next=\do_comment
    \else\if*\next\let\next=\do_comment
    \else\ifx/\next\let\next=\do_comment
    \else\let\next=\normal_slash
    \fi\fi\fi
    \next
   }

}


{\catcode`\~=13 % uccode trick
\catcode`\^^M=13 \endlinechar=-1 % ignore newlines

\gdef\do_comment#1%
   {\egroup % ends group with program text
    \bgroup % starts group with comment
	\if!#1%
	     \sl
	     \ifx\comment_tp\relax{\commentfont /!}\fi
	     \catcode`!=13 %
	     \uccode`~=`!\uppercase{\global\let~=\end_commentx}%
	     \let^^M=\comment_nl
	\else\if*#1%
	     \it
	     \ifx\comment_tp\relax{\commentfont /*}\fi
	     \catcode`*=13 %
	     \uccode`~=`*\uppercase{\global\let~=\end_comments}%
	     \let^^M=\comment_nl
	\else\it
	     \ifx\comment_tp\relax{\commentfont //}\fi
	     \let^^M=\prog_nl
	\fi\fi
	\gdef\comment_tp{#1}%
	\obeyspaces
	\tt_space
   }%
}

% A /! comment is ended with !/, a /* comment is ended with */, and
% a // comment is ended by a newline.

\def\end_commentx{\def\tmp{!}\futurelet\next\isend_comment}
\def\end_comments{\def\tmp{*}\futurelet\next\isend_comment}

\def\isend_comment
   {\if\next/{\commentfont\tmp/}\let\next=\end_comment
    \else\let\next=\tmp
    \fi
    \next
   }

\def\end_comment#1%
   {\egroup % ends group with comment
    \bgroup % starts group with program
	\prog_setup
   }

% A newline normally closes the box with the program, the box with the
% line, and sets the line. Then it starts a new line with a program box.
% But if a newline occurs in a /* or /! comment, the new line starts with
% a comment box instead.

\def\prog_nl
   {\egroup % ends program or comment group
    \egroup % ends line box
    \box\cc_box
    \start_prog
   }

\def\comment_nl
   {\egroup % ends comment group
    \egroup % ends line box
    \box\cc_box
    \setbox\cc_box=\hbox\bgroup % starts line box
	\kern\ccindent
	\bgroup % starts group for prog text (empty)
	\expandafter\do_comment\comment_tp
   }

% The program is typeset in verbatim mode

{\catcode`\~=13 % uccode trick
\catcode`\^^M=13 \endlinechar=-1 % ignore newlines

\gdef\prog_setup
   {\def\do##1{\catcode`##1=12}\dospecials % make special chars normal
    \catcode`\/=13 % make `/' active
    \uccode`~=`/\uppercase{\global\let~=\start_comment}%
    \obeyspaces\tt
    \let^^M=\prog_nl
    \global\let\comment_tp=\relax
   }
}

\def\start_prog
   {\setbox\cc_box=\hbox\bgroup % start box with line
	\kern\ccindent
	\bgroup % start group with program
	    \prog_setup
	    \futurelet\next\is_endprog
   }

{\catcode`\/=0 /catcode`/\=12 % now / is escape char

% It is rather hard to check for the occurrence of `\end{cc}'. For
% convenience, assume that no `\' will occur as first char of a line,
% unless the line contains \end{cc}. Hence, at the beginning of a line
% we check if there is a `\', and if so, we terminate the environment.

/gdef/is_endprog
   {/if\/next/let/next=/do_endprog
    /else/let/next=/relax
    /fi
    /next
   }

/catcode`[=1 /catcode`]=2 % begin and engroup chars
/catcode`{=12 /catcode`}=12
/gdef/do_endprog#1\end{cc}%
   [/egroup % closes program group
    /egroup % closes line box
    /egroup % matches \setupcc
    /end[cc]% to match LaTeX's \begin{cc}
   ]
]

\def\setupcc
   {\par
    \bgroup
	\let\par=\start_prog
	\obeylines
   }

% we use \tt spacing

{\obeyspaces\gdef\tt_space{\def {{\tt\ }}}}

\let\commentfont=\tt

% define the environment:

\newenvironment{cc}{\bigskip\setupcc}{\bigskip}

\catcode`\_=\tmp % restore catcode

